package LPU;

import java.util.ArrayList;

import org.ejml.data.DenseMatrix64F;
import org.ejml.ops.*;

public class RNuseRoc {
	private int wordCount;
	public ArrayList<String> pos;
	public ArrayList<String> unlabel;
	public ArrayList<String> rn;
	
	public RNuseRoc(int wordNum, ArrayList<String> posDocs, ArrayList<String> unlabelDocs){
		this.wordCount = wordNum;
		this.pos = posDocs;
		this.unlabel = unlabelDocs;
		rn = new ArrayList<String>();
	}
	public void run(){
		getRNbyRoc();
	}
	
	public void getRNbyRoc(){
		DenseMatrix64F posMatrix = new DenseMatrix64F(pos.size(), wordCount);
		DenseMatrix64F unlabelMatrix = new DenseMatrix64F(unlabel.size(), wordCount);
		
		DenseMatrix64F vectorPos = caculateStandardVector(posMatrix, pos);
		DenseMatrix64F vectorUnlabel = caculateStandardVector(unlabelMatrix, unlabel);
		
		double alphaP = 16.0 / pos.size(), alphaU = 16.0/unlabel.size();
		double beltaP = 4.0/(0-unlabel.size()), beltaU = 4.0/(0-pos.size()); 
		DenseMatrix64F standardPos = new DenseMatrix64F(1, wordCount);
		CommonOps.add(alphaP, vectorPos, beltaP, vectorUnlabel, standardPos);
		DenseMatrix64F standardUnlabel = new DenseMatrix64F(1, wordCount);
		CommonOps.add(alphaU, vectorUnlabel, beltaU, vectorPos, standardUnlabel);
		
		for(String unlabelDoc : this.unlabel){
			DenseMatrix64F curVector = new DenseMatrix64F(1, wordCount);
			String[] TFpairs = unlabelDoc.split(" ");	
			for(int j = 1; j < TFpairs.length; j++){
				String TFpair = TFpairs[j];
				int wordIndex = Integer.parseInt(TFpair.split(":")[0]);
				int termFrequency = (int)Double.parseDouble(TFpair.split(":")[1]);
				curVector.set(0, wordIndex, termFrequency);
			}
			
			if(calcualteSimilarity(curVector, standardPos) < calcualteSimilarity(curVector, standardUnlabel))
				this.rn.add(unlabelDoc);
		}
		
		this.unlabel.removeAll(rn);
	}
	
	public double calcualteSimilarity(DenseMatrix64F vector1, DenseMatrix64F vector2){
		double length1=0, length2=0;
		double sim=0;
		int colIndex=0;
		
		for(colIndex=0; colIndex<this.wordCount; colIndex++){
			double value1 = vector1.get(0, colIndex);
			double value2 = vector2.get(0, colIndex);
			sim = sim + (value1*value2); 
			length1 += Math.pow(value1, 2);
			length2 += Math.pow(value2, 2);
		}
		length1 = Math.sqrt(length1);
		length2 = Math.sqrt(length2);
		
		return sim/(length1*length2);
	}
	
	public DenseMatrix64F caculateStandardVector(DenseMatrix64F matrix, ArrayList<String> docs){
		for(int i = 0; i < docs.size(); i++){
			String curPos = docs.get(i);
			String[] TFpairs = curPos.split(" ");	
			for(int j = 1; j < TFpairs.length; j++){
				String TFpair = TFpairs[j];
				int wordIndex = Integer.parseInt(TFpair.split(":")[0]);
				int termFrequency = (int)Double.parseDouble(TFpair.split(":")[1]);
				matrix.set(i, wordIndex, termFrequency);
			}
		}	
		int rowIndex=0, colIndex=0;
		//sigma pos docs
		for(rowIndex=0; rowIndex<docs.size(); rowIndex++){
			double rowLength=0;
			for(colIndex=0; colIndex<this.wordCount; colIndex++){
				rowLength += Math.pow(matrix.get(rowIndex, colIndex), 2);
			}
			rowLength = Math.sqrt(rowLength);
			for(colIndex=0; colIndex<this.wordCount; colIndex++){
				matrix.set(rowIndex, colIndex, matrix.get(rowIndex, colIndex)/rowLength);
			}
		}
		DenseMatrix64F colSum = new DenseMatrix64F(1, wordCount);
		CommonOps.sumCols(matrix, colSum);
		
		return colSum;
	}
}
